home *** CD-ROM | disk | FTP | other *** search
/ Especial Multimedia / Especial Multimedia.iso / Multimed / Prg / APMMETA.ZIP / APMMETA.C < prev    next >
C/C++ Source or Header  |  1997-09-14  |  10KB  |  369 lines

  1. /**************************************************************************
  2.  *                                                                        *
  3.  *   Library to support APM-Metafiles for VisualBasic                     *
  4.  *                                                                        *
  5.  *   Name            : APMMETA.C                                          *
  6.  *   Author          : U. Reisewitz CIS 100042,47                         *
  7.  *   created         : 01/20/92                                           *
  8.  *                                                                        *
  9.  **************************************************************************/
  10.  
  11.  
  12. #include   <windows.h>
  13. #include   <stdlib.h>
  14. #include   <io.h>
  15.  
  16. typedef struct
  17. {
  18.    DWORD       dwKey;
  19.    HANDLE      hMF;
  20.    RECT        rcBBox;
  21.    WORD        wInch;
  22.    DWORD       dwReserved;
  23.    WORD        wChecksum;
  24. }  APMHEADER;
  25.  
  26. typedef struct
  27. {
  28.    HANDLE      hMetaMem;
  29.    short       Left;
  30.    short       Top;
  31.    short       Right;
  32.    short       Bottom;
  33. }  METABITMAP;
  34.  
  35.  
  36. #define        BLSIZE  2048
  37.  
  38.  
  39. /**************************************************************************
  40.     Declaration of external procedures
  41.  **************************************************************************/
  42.  
  43.  
  44.  
  45.  
  46. /**************************************************************************
  47.     Declaration of internal procedures
  48.  **************************************************************************/
  49.  
  50. int  far pascal LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize,
  51.                         LPSTR lpszCmdLine);
  52. int  far pascal LoadAPMetaFile(char far *FileName, APMHEADER far *APMHdr);
  53. int  far pascal CreateMemhDC(APMHEADER far *APMHdr, METABITMAP far *MetaBmp,
  54.                              HANDLE hDC);
  55. int  far pascal CopyMemToDev(METABITMAP far *MetaBmp, HANDLE hDC,
  56.                              int Xorg, int Yorg);
  57. void far pascal ClearMemhDC(METABITMAP far *MetaBmp);
  58.  
  59.  
  60.  
  61.  
  62. /**************************************************************************
  63.     Declaration of global variables
  64.  **************************************************************************/
  65.  
  66.  
  67. HANDLE          hOurInstance;
  68.  
  69.  
  70. /**************************************************************************
  71.     LibMain   - Is called by LibEntry.  LibEntry is called by Windows when
  72.                 the DLL is loaded. It initializes the DLL's heap and then
  73.                 calls LibMain.
  74.  **************************************************************************/
  75.  
  76. int far pascal LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize,
  77.                        LPSTR lpszCmdLine)
  78. {
  79.     hOurInstance = hModule;
  80.     LocalInit(wDataSeg, 0, cbHeapSize);
  81.  
  82.     return (TRUE);
  83. }
  84.  
  85.  
  86.  
  87. /**************************************************************************
  88.     LoadAPMetaFile    - Load Windows Metafile. The APM-Metafile will be
  89.                         opened and copied to a Memory-Metafile. The
  90.                         APM-Headerstructure is returned to the
  91.                         calling process.
  92.  **************************************************************************/
  93.  
  94. int far pascal LoadAPMetaFile(char far *FileName, APMHEADER far *APMHdr)
  95. {
  96.    GLOBALHANDLE    hData;
  97.    int             fh;
  98.    char _huge      *hpData;
  99.    char _huge      *hpDataR;
  100.    DWORD           dwReadSize;
  101.    WORD            wSteps, wReadRest, wAktStep;
  102.    METAHEADER      mfHeader;
  103.    int             RetVar, i;
  104.    WORD            TChecksum;
  105.    WORD far        *pWord;
  106.    DWORD           FileStat;
  107.  
  108.  
  109.    // initialize or return value
  110.  
  111.    RetVar = 0;
  112.  
  113.    // open the APM-File
  114.  
  115.    fh = _lopen(FileName, OF_SHARE_DENY_WRITE);
  116.    if (fh == -1)
  117.    {
  118.        RetVar = 1;
  119.        goto ExLoadAPMetaFile;
  120.    }
  121.  
  122.    // we start at the beginning...
  123.  
  124.    _llseek(fh, 0, 0);
  125.  
  126.  
  127.    // read the APM-Header
  128.  
  129.    FileStat =_lread(fh, (LPSTR) APMHdr, sizeof(APMHEADER));
  130.    if (FileStat < 0)
  131.    {
  132.        RetVar = 2;
  133.        goto ExLoadAPMetaFile;
  134.    }
  135.  
  136.  
  137.    // Test checksum
  138.  
  139.    pWord = (WORD far *) APMHdr;
  140.    TChecksum = 0;
  141.  
  142.    for (i = 0; i < 10; i++)
  143.        TChecksum ^= pWord[i];
  144.  
  145.    if (TChecksum != APMHdr->wChecksum)
  146.    {
  147.        RetVar = 3;
  148.        goto ExLoadAPMetaFile;
  149.    }
  150.  
  151.    // Read windows-metafile-header
  152.  
  153.    _llseek(fh, sizeof(APMHEADER), 0);
  154.    FileStat = _lread(fh, (LPSTR) &mfHeader, sizeof(mfHeader));
  155.    if (FileStat < 0)
  156.    {
  157.        RetVar = 4;
  158.        goto ExLoadAPMetaFile;
  159.    }
  160.  
  161.    // allocate memory for metafile
  162.  
  163.    dwReadSize = mfHeader.mtSize * 2L;
  164.  
  165.    if (! (hData = GlobalAlloc(GHND, dwReadSize)))
  166.    {
  167.        RetVar = 5;
  168.        goto ExLoadAPMetaFile;
  169.    }
  170.  
  171.    // we use a huge pointer. because of that we are able to
  172.    // support metafiles larger than 64 kBytes
  173.  
  174.    if (! (hpData = (char _huge *) GlobalLock(hData)))
  175.    {
  176.        GlobalFree(hData);
  177.        RetVar = 6;
  178.        goto ExLoadAPMetaFile;
  179.    }
  180.  
  181.    // if you have WINDOWS 3.1, you may use the block with the
  182.    // remarks. it uses the new _hread-function, which is able
  183.    // to read more than 64 kBytes at once
  184.  
  185.    if (dwReadSize > 65536L)
  186.    {
  187.        wSteps = (WORD) (dwReadSize / BLSIZE);
  188.        wReadRest = (WORD) (dwReadSize % BLSIZE);
  189.    }
  190.    else
  191.    {
  192.        wSteps = 0;
  193.        wReadRest = (WORD) dwReadSize;
  194.    }
  195.  
  196.    hpDataR = hpData;
  197.  
  198.    _llseek(fh, sizeof(APMHEADER), 0);
  199.  
  200.    for (wAktStep = 0; wAktStep < wSteps; wAktStep++)
  201.    {
  202.        FileStat = _lread(fh, hpDataR, BLSIZE);
  203.        if (FileStat < 0)
  204.        {
  205.            GlobalUnlock(hData);
  206.            GlobalFree(hData);
  207.            RetVar = 7;
  208.            goto ExLoadAPMetaFile;
  209.        }
  210.        hpDataR += BLSIZE;
  211.    }
  212.  
  213.    FileStat = _lread(fh, hpDataR, wReadRest);
  214.    if (FileStat < 0)
  215.    {
  216.        GlobalUnlock(hData);
  217.        GlobalFree(hData);
  218.        RetVar = 8;
  219.        goto ExLoadAPMetaFile;
  220.    }
  221.  
  222.    //  FileStat = _hread(fh, hpData, dwReadSize);
  223.    //  if ((FileStat == -1L) || (FileStat != dwReadSize))
  224.    //  {
  225.    //      GlobalUnlock(hData);
  226.    //      GlobalFree(hData);
  227.    //      RetVar = 8;
  228.    //      goto ExLoadAPMetaFile;
  229.    //  }
  230.  
  231.    // close the file, we don't need it any more
  232.  
  233.    FileStat = _lclose(fh);
  234.    fh = 0;
  235.    if (FileStat != 0L)
  236.    {
  237.        GlobalUnlock(hData);
  238.        RetVar = 9;
  239.        goto ExLoadAPMetaFile;
  240.    }
  241.  
  242.    GlobalUnlock(hData);
  243.  
  244.    // now we create a windows metafile out of our memoryblock
  245.  
  246.    if (! (APMHdr->hMF = SetMetaFileBits(hData)))
  247.    {
  248.        RetVar = 10;
  249.        goto ExLoadAPMetaFile;
  250.    }
  251.  
  252.  
  253. ExLoadAPMetaFile:
  254.    if (fh != 0)        // something was wrong
  255.        _lclose(fh);
  256.  
  257.    return (RetVar);
  258.  
  259. }
  260.  
  261.  
  262. /**************************************************************************
  263.     CreateMemhDC      - creates a device-compatible bitmap from a
  264.                         given metafile. The bitmap-information is
  265.                         returned in a METABITMAP-structure.
  266.  **************************************************************************/
  267.  
  268. int far pascal CreateMemhDC(APMHEADER far *APMHdr, METABITMAP far *MetaBmp,
  269.                            HANDLE hDC)
  270. {
  271.    long            PixPerInchX, PixPerInchY, PixelsX, PixelsY;
  272.    HBITMAP         hBitMap;
  273.    int             RetVar = 0;
  274.  
  275.    // if the device doesn't support BITBLT, we can stop here
  276.  
  277.    RetVar = GetDeviceCaps(hDC, RASTERCAPS);
  278.    if ((RetVar & RC_BITBLT) == 0)
  279.    {
  280.        RetVar = 1;
  281.        goto ExCreateMemhDC;
  282.    }
  283.  
  284.    PixPerInchX = GetDeviceCaps(hDC, LOGPIXELSX);
  285.    PixPerInchY = GetDeviceCaps(hDC, LOGPIXELSY);
  286.  
  287.    // size the metafile to its original size
  288.  
  289.    MetaBmp->Left = 0;
  290.    MetaBmp->Right = (short) (PixPerInchX *
  291.                     abs(APMHdr->rcBBox.right - APMHdr->rcBBox.left) /
  292.                     APMHdr->wInch);
  293.  
  294.    MetaBmp->Top = 0;
  295.    MetaBmp->Bottom = (short) (PixPerInchY *
  296.                      abs(APMHdr->rcBBox.bottom - APMHdr->rcBBox.top) /
  297.                      APMHdr->wInch);
  298.  
  299.    MetaBmp->hMetaMem = CreateCompatibleDC(hDC);
  300.  
  301.    // now create a bitmap that is compatible with the device
  302.    // we want to use
  303.  
  304.    hBitMap = CreateCompatibleBitmap(hDC, MetaBmp->Right, MetaBmp->Bottom);
  305.  
  306.    SelectObject(MetaBmp->hMetaMem, hBitMap);
  307.  
  308.    RetVar = PatBlt(MetaBmp->hMetaMem, 0, 0,
  309.                    MetaBmp->Right, MetaBmp->Bottom, WHITENESS);
  310.  
  311.    SetMapMode(MetaBmp->hMetaMem, MM_ANISOTROPIC);
  312.  
  313.    // play the metafile "into the device context"
  314.    // after that, we have a bitmap which can be transferred
  315.    // to the printer as many times as we like with a
  316.    // simple BITBLT-command
  317.  
  318.    SaveDC(MetaBmp->hMetaMem);
  319.    SetViewportOrg(MetaBmp->hMetaMem, 0, 0);
  320.    SetViewportExt(MetaBmp->hMetaMem, MetaBmp->Right, MetaBmp->Bottom);
  321.    RetVar = PlayMetaFile(MetaBmp->hMetaMem, APMHdr->hMF);
  322.    RestoreDC(MetaBmp->hMetaMem, -1);
  323.  
  324.    // we don`t need the metafile any more
  325.  
  326.    RetVar = DeleteMetaFile(APMHdr->hMF);
  327.  
  328.    RetVar = 0;
  329.  
  330. ExCreateMemhDC:
  331.    return(RetVar);
  332.  
  333. }
  334.  
  335.  
  336. /**************************************************************************
  337.     CopyMemToDev      - copies the content of a device-compatible bitmap
  338.                         to the physical device.
  339.  **************************************************************************/
  340.  
  341. int far pascal CopyMemToDev(METABITMAP far *MetaBmp, HANDLE hDC,
  342.                             int Xorg, int Yorg)
  343. {
  344.    int RetVar;
  345.  
  346.    SetMapMode(hDC, GetMapMode(MetaBmp->hMetaMem));
  347.  
  348.    // it's unbelievable, that's really all!!!
  349.  
  350.    RetVar = BitBlt(hDC, Xorg, Yorg,
  351.                    MetaBmp->Right, MetaBmp->Bottom,
  352.                    MetaBmp->hMetaMem, 0, 0, SRCCOPY);
  353.  
  354.    return(RetVar);
  355. }
  356.  
  357.  
  358. /**************************************************************************
  359.     ClearMemhDC       - deletes a device-compatible bitmap.
  360.  **************************************************************************/
  361.  
  362. void far pascal ClearMemhDC(METABITMAP far *MetaBmp)
  363. {
  364.    // garbage collection
  365.  
  366.    DeleteDC(MetaBmp->hMetaMem);
  367.    return;
  368. }
  369.